package cooperated

import (
	"gddgame.cc/galaxy/common/namespaces/cooperate"
	"gddgame.cc/galaxy/common/namespaces/cooperate/structure"
	"gddgame.cc/galaxy/utils"
)

func (logic *TypeMap) Hold(info InfoContainer, hold *HoldLogic) {
	target := info.GetTarget()
	result := logic.GetDetailCache(logic, info.GetTarget())
	holdStatus := NoneHoldStatus
	//identity := 0
	position := utils.ToBytes(target.Id)
	if result != nil {
		//identity = result.ToInt(Identity)
		holdStatus = result.ToByte(HoldStatus)
		position = result.ToBytes(Position)
	}
	holdData := logic.GetDetailCache(logic, &hold.Data)
	if holdData == nil {
		// 任务对象死亡
		return
	}
	switch info.GetTarget().GetDataType() {
	case NodeType:
		newStatus := hold.Status
		identity := 0
		//fmt.Println(hold, holdStatus, newStatus)
		if holdStatus == newStatus {
			return
		}
		if newStatus == DestroyHoldStatus {
			identity = 0
			// 如果销毁，则开始进行占领逻辑
			logic.continueHold(info, position, hold)
		} else if newStatus == HoldedStatus {
			identity = hold.Identity
		}
		logic.switchBaseHold(info, position, identity, newStatus, hold, "")

		//// 小据点判断
		//nodeIndex := logic.singeIndexMap[utils.ToString(info.BaseData.Id)]
		//node := logic.Map.SingleBase[nodeIndex]
		//transform, nodeIdentity := logic.processParentBase(conn, info, node, position, identity, "single")
		//
		//if !transform {
		//	return
		//}
		//// 大据点判断
		//position = node.Position
		//nodeIndex = logic.fightIndexMap[utils.ToString(node.Position)]
		//node = logic.Map.FightBase[nodeIndex]
		//transform, _ = logic.processParentBase(conn, info, node, position, nodeIdentity, "fight")
		//if transform {
		//	// 通知所有人, 通过operate会自动通知
		//}
	}
}
func (logic *TypeMap) processParentBase(info InfoContainer, node cooperate.RangeDefineNode, position []byte, identity int, key string) (bool, int) {
	idString := utils.ToString(position)
	// 判断据点状态
	nodeResult := logic.GetPropsCache(logic, structure.NewBaseData(NodeType, node.Position), []string{Identity + key})
	nodeIdentity := utils.ToInt(nodeResult[Identity+key])
	var holdStatus byte
	var tmp int
	sameNumber := 0
	diffNumber := 0
	if nodeIdentity != identity {
		switch key {
		case "single":
			// 全都突破，切换状态
		case "fight":
			if identity == 0 {
				// 有一个被突破，切换状态
				nodeIdentity = 0
				holdStatus = DestroyHoldStatus
				goto SwitchFight
			} else {
				// 有一个占领，需要判断其余子节点
			}
		}

	} else {
		// 子节点变化后和主节点相同，应该是争夺中，无需后续处理
		return false, nodeIdentity
	}
	tmp = nodeIdentity
	for _, p := range node.Range {
		var ii int
		if utils.ToString(p) == idString {
			ii = identity
		} else {
			result := logic.GetPropsCache(logic, structure.NewBaseData(NodeType, p), []string{Identity})
			ii = utils.ToInt(result[Identity])
		}
		if ii != nodeIdentity {
			diffNumber += 1
		}
		if ii != tmp {
			tmp = ii
			sameNumber = 1
		} else {
			sameNumber += 1
		}
	}
	if sameNumber < len(node.Range) {
		switch key {
		case "single":
			if nodeIdentity != 0 && diffNumber == len(node.Range) {
				// 占领中，需要全部不被原有势力占领才算摧毁
				holdStatus = DestroyHoldStatus
				nodeIdentity = 0

				goto SwitchFight
			}
		}
		// 所有子节点并不相同
		return false, nodeIdentity
	} else {
		nodeIdentity = tmp
		holdStatus = HoldedStatus
	}
SwitchFight:
	logic.switchBaseHold(info, node.Position, nodeIdentity, holdStatus, nil, key)
	return true, nodeIdentity
}
func (logic *TypeMap) switchBaseHold(info InfoContainer, position []byte, identity int, holdStatus byte, hold *HoldLogic, key string) {
	if holdStatus != HoldedStatus {
		identity = 0
	}
	//fmt.Println("hold", holdStatus, key)
	operateData := &cooperate.UpdateOperateData{
		Data: *structure.NewBaseData(NodeType, position),
		Operates: []cooperate.UpdateOperateContent{{
			Operate: cooperate.ChangeData,
			Key:     Identity + key,
			Value:   identity,
		}},
	}
	if key == "" {
		operateData.Operates = append(operateData.Operates, cooperate.UpdateOperateContent{
			Operate: cooperate.ChangeData,
			Key:     HoldStatus,
			Value:   holdStatus,
		})
	}
	// 需要比message早一步下发
	logic.scheduleBatchUpdateOperate2(info, operateData, -100)
	extend := cooperate.NewPositionModeExtend(logic.GetMapNoId(), position)
	dd := structure.NewBaseData(NodeType, position)
	if identity > 0 {
		logic.Mode(logic, info.GetTarget(), dd, *logic.Event.OnHoldBase, info.GetTime(), extend)
		if hold != nil {
			logic.Mode(logic, info.GetTarget(), &hold.Data, *logic.Event.OnHoldBase, info.GetTime(), extend)
		}
	} else {
		logic.Mode(logic, info.GetTarget(), dd, *logic.Event.OnDestroyBase, info.GetTime(), extend)
		if hold != nil {
			logic.Mode(logic, info.GetTarget(), &hold.Data, *logic.Event.OnDestroyBase, info.GetTime(), extend)
		}
	}
}
func (logic *TypeMap) moveArriveHold(info *structure.ScheduleInfo, position []byte, selfIdentity int) {
	// 占领逻辑
	_, ok := logic.regionIndexMap[utils.ToString(position)]
	if ok {
		dd := structure.NewBaseData(NodeType, position)
		node := logic.GetPropsCache(logic, dd, []string{Identity, HoldStatus})
		holdIdentity := utils.ToInt(node[Identity])
		holdStatus := utils.ToByte(node[HoldStatus])
		time := info.Time
		switch holdStatus {
		case NoneHoldStatus:
			// 直接开始占领
			extend := cooperate.NewModeExtend([]interface{}{logic.HoldTime}, info.MapNoId, nil, position)
			logic.Mode(logic, info.From, info.Target, *logic.Event.HoldBase, info.Time, extend)
			time += int64(logic.HoldTime)
			holdStatus = HoldedStatus
			//fmt.Println("hold")
		case HoldedStatus:
			// 同势力不处理，敌对势力，开始销毁
			if _, isEnerm := logic.JudgeIdentity(holdIdentity, selfIdentity); isEnerm {
				extend := cooperate.NewModeExtend([]interface{}{logic.DestroyTime}, info.MapNoId, nil, position)
				logic.Mode(logic, info.From, info.Target, *logic.Event.DestroyBase, info.Time, extend)
				time += int64(logic.DestroyTime)
				holdStatus = DestroyHoldStatus
				//fmt.Println("destroy")
			} else {
				holdStatus = NoneHoldStatus
			}
		case DestroyHoldStatus:
			// 开始占领
			extend := cooperate.NewModeExtend([]interface{}{logic.HoldTime}, info.MapNoId, nil, position)
			logic.Mode(logic, info.From, info.Target, *logic.Event.HoldBase, info.Time, extend)
			time += int64(logic.HoldTime)
			holdStatus = HoldedStatus
		}
		if holdStatus != NoneHoldStatus {
			holdLogic := &HoldLogic{Data: *info.Target, Status: holdStatus, Identity: selfIdentity & BaseIdentityType}
			_ = logic.AddTouchSchedule(info.MapNoId, &cooperate.ScheduleContent{
				From:   info.Target,
				Target: dd,
				Key:    "hold",
				Time:   time,
			}, 1, position, HoldLogicType, holdLogic, nil)
			operateData := &cooperate.UpdateOperateData{
				Data: *info.Target,
				Operates: []cooperate.UpdateOperateContent{{
					Operate: cooperate.ChangeDateTime,
					Key:     HoldBaseTime,
					Value:   time,
				}},
			}
			logic.scheduleBatchUpdateOperate2(info, operateData, 0)
		}
	}
}
func (logic *TypeMap) continueHold(info InfoContainer, position []byte, hold *HoldLogic) {
	// 继续占领
	extend := cooperate.NewModeExtend([]interface{}{logic.HoldTime}, logic.GetMapNoId(), nil, position)
	logic.Mode(logic, info.GetTarget(), &hold.Data, *logic.Event.HoldBase, info.GetTime(), extend)
	time := info.GetTime() + int64(logic.HoldTime)
	//fmt.Println("hold continue")
	holdLogic := &HoldLogic{Data: hold.Data, Status: HoldedStatus, Identity: hold.Identity & BaseIdentityType}
	_ = logic.AddTouchSchedule(logic.GetMapNoId(), &cooperate.ScheduleContent{
		From:   info.GetTarget(),
		Target: structure.NewBaseData(NodeType, position),
		Key:    "holdContinue",
		Time:   time,
	}, 1, position, HoldLogicType, holdLogic, nil)
	operateData := &cooperate.UpdateOperateData{
		Data: hold.Data,
		Operates: []cooperate.UpdateOperateContent{{
			Operate: cooperate.ChangeDateTime,
			Key:     HoldBaseTime,
			Value:   time,
		}},
	}
	logic.scheduleBatchUpdateOperate2(info, operateData, 0)
}
func (logic *TypeMap) breakHold(info InfoContainer, position []byte) {
	extend := cooperate.NewPositionModeExtend(logic.GetMapNoId(), position)
	//fmt.Println("break", info.BaseData)
	// 中断，并且取消计划任务
	logic.Mode(logic, info.GetFrom(), info.GetTarget(), *logic.Event.BreakBase, info.GetTime(), extend)
	dd := structure.NewBaseData(NodeType, position)
	operateData := []cooperate.OperateData{
		cooperate.NewOperateData(cooperate.BatchUpdateOperate, &cooperate.UpdateOperateData{
			Data: *info.GetTarget(),
			Operates: []cooperate.UpdateOperateContent{{
				Operate: cooperate.ChangeData,
				Key:     HoldBaseTime,
				Value:   0,
			}},
		}),
		cooperate.NewOperateData(cooperate.BatchUpdateOperate, &cooperate.UpdateOperateData{
			Data: *dd,
			Operates: []cooperate.UpdateOperateContent{{
				Operate: cooperate.RemoveSchedule,
				Key:     "hold",
			}, {
				Operate: cooperate.RemoveSchedule,
				Key:     "holdContinue",
			}},
		}),
	}
	logic.scheduleOperate2(info, operateData, -100)
}
